#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>

// 定义一个嵌套结构体
struct Address {
    char city[20];
    int zipCode;
    double latitude; // 新增 double 类型
};

// 定义一个 Friend 结构体（柔性数组的元素类型）
struct Friend {
    char name[20];
    int age;
};

// 定义一个包含多种数据类型的结构体
struct Person {
    char name[20];          // 字符数组
    int age;                // 整型
    float height;           // 浮点型
    double weight;          // 双精度浮点型
    char *phoneNumber;      // 字符指针
    int scores[3];          // 整型数组
    struct Address address; // 嵌套结构体
    unsigned char flags;    // 无符号字符
    void *metadata;         // void* 指针
    struct Friend friends[]; // 柔性数组（结构体类型）
};

// 定义 FieldInfo 结构体
struct FieldInfo {
    const char *name;         // 字段名称
    size_t offset;            // 字段在结构体中的偏移量
    size_t size;              // 字段的大小
    const void *nestedStructDef; // 指向嵌套结构体的定义（如果是嵌套结构体）
};

// 函数：打印字段的名称、偏移量和字节内容（单行展示）
void printFieldInfo(const void *base, const char *fieldName, size_t offset, size_t size) {
    const unsigned char *bytes = (const unsigned char *)base + offset;
    printf("Field: %-15s | Offset: %-4zu | Bytes: ", fieldName, offset);
    for (size_t i = 0; i < size; i++) {
        printf("%02x ", bytes[i]); // 以十六进制格式打印每个字节
    }
    printf("\n");
}

// 函数：递归打印结构体中的所有字段（包括嵌套结构体）
void printStructFields(const void *base, const char *structName, const struct FieldInfo *fields, size_t structSize, size_t flexibleArraySize) {
    printf("=== Struct: %s ===\n", structName);
    printFieldInfo(base, structName, 0, structSize); // 打印整个结构体的字节内容

    // 遍历字段信息
    for (size_t i = 0; fields[i].name != NULL; i++) {
        // 优先处理柔性数组
        if (strcmp(fields[i].name, "friends") == 0) {
            // 特别处理柔性数组
            const unsigned char *flexibleArrayBase = (const unsigned char *)base + fields[i].offset;
            for (size_t j = 0; j < flexibleArraySize / sizeof(struct Friend); j++) {
                char elementName[50];
                snprintf(elementName, sizeof(elementName), "friends[%zu]", j);
                printStructFields(flexibleArrayBase + j * sizeof(struct Friend), elementName, (const struct FieldInfo *)fields[i].nestedStructDef, sizeof(struct Friend), 0);
            }
        } else if (fields[i].nestedStructDef != NULL) {
            // 递归处理嵌套结构体
            printf("----- %d \n", sizeof(fields[i].size)); // 整个结构体的大小
            printf("----- %d \n", sizeof(fields[i].size));
            printStructFields((const unsigned char *)base + fields[i].offset, fields[i].name, (const struct FieldInfo *)fields[i].nestedStructDef, fields[i].size, 0);
        } else {
            // 打印普通字段
            printFieldInfo(base, fields[i].name, fields[i].offset, fields[i].size);
        }
    }
}

int main() {
    // 动态分配内存以支持柔性数组
    size_t friendsCount = 3;
    size_t personSize = sizeof(struct Person) + friendsCount * sizeof(struct Friend);
    struct Person *person = (struct Person *)malloc(personSize);
    if (person == NULL) {
        perror("Failed to allocate memory");
        return 1;
    }
    memset(person, 0, personSize);

    // 初始化结构体实例
    strcpy(person->name, "Alice");
    person->age = 25;
    person->height = 1.75f;
    person->weight = 60.5;
    person->phoneNumber = "123-456-7890";
    person->scores[0] = 90;
    person->scores[1] = 85;
    person->scores[2] = 95;
    strcpy(person->address.city, "New York");
    person->address.zipCode = 10001;
    person->address.latitude = 40.7128;
    person->flags = 0xAB;

    // 初始化 void* 指针
    int metadataValue = 0xDEADBEEF;
    person->metadata = &metadataValue;

    // 初始化柔性数组（结构体类型）
    for (size_t i = 0; i < friendsCount; i++) {
        snprintf(person->friends[i].name, sizeof(person->friends[i].name), "Friend%d", (int)(i + 1));
        person->friends[i].age = 20 + (int)i;
    }

    // 定义 Friend 结构体的字段信息
    const struct FieldInfo friendFields[] = {
        {"name", offsetof(struct Friend, name), sizeof(person->friends[0].name), NULL},
        {"age", offsetof(struct Friend, age), sizeof(person->friends[0].age), NULL},
        {NULL, 0, 0, NULL} // 结束标记
    };

    printf("height ==%d \n ", sizeof(person->height));
    // 定义 Person 结构体的字段信息（包含嵌套的 Address 和 Friend 结构体字段信息）
    const struct FieldInfo personFields[] = {
        {"name", offsetof(struct Person, name), sizeof(person->name), NULL},
        {"age", offsetof(struct Person, age), sizeof(person->age), NULL},
        {"height", offsetof(struct Person, height), sizeof(person->height), NULL},
        {"weight", offsetof(struct Person, weight), sizeof(person->weight), NULL},
        {"phoneNumber", offsetof(struct Person, phoneNumber), sizeof(person->phoneNumber), NULL},
        {"scores", offsetof(struct Person, scores), sizeof(person->scores), NULL},
        {"address", offsetof(struct Person, address), sizeof(person->address), (const struct FieldInfo[]){
            {"city", offsetof(struct Address, city), sizeof(person->address.city), NULL},
            {"zipCode", offsetof(struct Address, zipCode), sizeof(person->address.zipCode), NULL},
            {"latitude", offsetof(struct Address, latitude), sizeof(person->address.latitude), NULL},
            {NULL, 0, 0, NULL} // 结束标记
        }},
        {"flags", offsetof(struct Person, flags), sizeof(person->flags), NULL},
        {"metadata", offsetof(struct Person, metadata), sizeof(person->metadata), NULL},
        {"friends", offsetof(struct Person, friends), friendsCount * sizeof(struct Friend), friendFields}, // 柔性数组（结构体类型）
        {NULL, 0, 0, NULL} // 结束标记
    };

    // 打印结构体中的所有字段（包括嵌套结构体）
    printStructFields(person, "Person", personFields, sizeof(struct Person), friendsCount * sizeof(struct Friend));

    // 释放动态分配的内存
    free(person);

    return 0;
}